#include "vfs.h"


// 初始化 DIR_S 结构体
void init_dir(DIR_S *dir, int initial_capacity) {
    dir->capacity = initial_capacity;
    dir->size = 0;
    dir->arr = malloc(initial_capacity * sizeof(void*));
    if (!dir->arr) {
        exit(1);
    }
}

// 添加元素到 DIR_S 的 arr 数组中
void add_element(DIR_S *dir, DIR_S *element) {
    if (dir->size >= dir->capacity) { 
        size_t new_capacity = dir->capacity * 2;
        void **new_arr = realloc(dir->arr, new_capacity * sizeof(void*));
        if (!new_arr) {
            exit(1);
        }
        dir->arr = new_arr;
        dir->capacity = new_capacity;
    }
    dir->arr[dir->size++] = element;
    element->flag = 1; // 标记为已添加
}



void printTree(DIR_S *dir, int depth) {

    for (int i = 0; i < depth; ++i) printf("  ");
    if (dir->isLast == 1)
    {
        printf("└── %s (%s) \n", dir->filename, dir->fileType);
    }else{
        printf("├── %s (%s) \n", dir->filename, dir->fileType);
    }
    
    for (int j = 0; j < dir->size; ++j) {
        printf("│   ");
        printTree((DIR_S*)dir->arr[j], depth + 1);
    }
}



int initDb(DBINFO *dbinfo){
    dbinfo->server = "localhost";
    dbinfo->user = "root";
    dbinfo->password = "123456";
    dbinfo->database = "zcs";
    return 0;
}

//mysql相关
void * queryInfo(void *arg){
    SQL *sql = (SQL *)arg;

    // 计算所需内存大小
    size_t bufferSize = 1024;
    char *buffer = (char*)malloc(bufferSize);
    if (!buffer) return NULL;
    snprintf(buffer, bufferSize, "SELECT ");
    for (int i = 0; i < sql->queryNum; i++){
        strncat(buffer,sql->para[i],bufferSize - strlen(buffer) - 1);
        if (i < sql->queryNum - 1) {
            strncat(buffer, ", ", bufferSize - strlen(buffer) - 1);
        }
    }
    strncat(buffer, " FROM ", bufferSize - strlen(buffer) - 1);
    strncat(buffer, sql->tName, bufferSize - strlen(buffer) - 1);

    if (sql->paraNum - sql->queryNum > 0){
        strncat(buffer, " WHERE ", bufferSize - strlen(buffer) - 1);
        for (int i = sql->queryNum; i < sql->paraNum; ++i) {
            strncat(buffer, sql->para[i], bufferSize - strlen(buffer) - 1);
            if (i < sql->paraNum - 1) {
                strncat(buffer, " AND ", bufferSize - strlen(buffer) - 1);
            }
        }
    }
    buffer[bufferSize - 1] = '\0';
    return buffer;
}

//数据库连接测试函数
// 释放 DIR_S 结构体内存
void free_dir(DIR_S *dir) {
    if (!dir) return;
    if (dir->file_id)   free(dir->file_id);
    if (dir->filename)  free(dir->filename);
    if (dir->pid)       free(dir->pid);
    if (dir->fileType)  free(dir->fileType);
    if (dir->filepath)  free(dir->filepath);
    if (dir->arr) {
        free(dir->arr);
        dir->arr = NULL;
    }
    free(dir);
}
void freeDirs(DIR_S **dirs, int num) {
    if (!dirs) return;
    for (int i = 0; i < num; i++) {
        //printf("%d\n",i);
        if (dirs[i]) {
            free_dir(dirs[i]);
            dirs[i] = NULL;
        }
    }
}


void swap(DIR_S **left,DIR_S **right){
    DIR_S *tmp = *right;
    *right = *left;
    *left = tmp;
}

void sortDir(DIR_S *dir) {
    int left = 0, right = dir->size - 1;
    DIR_S **arr = (DIR_S **)dir->arr;
    while (left <= right) {
        arr[left]->isLast = 0;
        if (strcmp(arr[left]->fileType, "f") == 0) {
            swap(&arr[left], &arr[right--]);
        } else {
            left++;
        }
    }

    
    if (dir->size > 0) {
        arr[dir->size - 1]->isLast = 1;
    }
}

int compareDir(const void *c, const void *d) {
    DIR_S *a = *(DIR_S **)c;
    DIR_S *b = *(DIR_S **)d;
    return strcmp(a->filename, b->filename);
}

// 数据库连接测试函数
void *queryVFS(void *para,int *num,MYSQL *conn){
    char *uid = (char *)para;
    // int uid = (int) para;
    // 初始化数据库信息
    // DBINFO dbinfo;
    // initDb(&dbinfo);

    // // 初始化MySQL连接
    // MYSQL *conn = mysql_init(NULL);
    // if (conn == NULL) {
    //     return;
    // }

    // if (mysql_real_connect(conn, dbinfo.server, dbinfo.user, dbinfo.password, dbinfo.database, 0, NULL, 0) == NULL) {
    //     mysql_close(conn);
    //     return;
    // }

    // 初始化SQL结构体
    SQL sql;
    sql.conn = conn;
    sql.tName = "vfs";
    sql.para = malloc(sizeof(char*) * 6);//user_id = 1
    sql.para[0] = strdup("file_id");
    sql.para[1] = strdup("file_name");
    sql.para[2] = strdup("parent_id");
    sql.para[3] = strdup("file_type");
    sql.para[4] = strdup("file_path");
    char buffer[50]; 
    //处理不同的参数
    // snprintf(buffer, sizeof(buffer), "user_id = %d", uid); 
    snprintf(buffer, sizeof(buffer), "user_id = %s ", uid); 

    
    sql.para[5] = strdup(buffer); 

    sql.paraNum = 6;
    sql.queryNum = 5;
    char *sentence = (char *)queryInfo(&sql);
    printf("%s \n",sentence);
    if (mysql_query(sql.conn, sentence)) {
        goto cleanup;
    }
    sql.res = mysql_use_result(sql.conn);
    
    DIR_S** dirs = malloc(sizeof(DIR_S*) * 1024);
    while ((sql.row = mysql_fetch_row(sql.res)) != NULL) {//遍历行
        dirs[*num] = (DIR_S *)malloc(sizeof(DIR_S));
        dirs[*num]->file_id = strdup(sql.row[0]);
        dirs[*num]->filename = strdup(sql.row[1]);
        if(sql.row[2] != NULL){
            dirs[*num]->pid =  strdup(sql.row[2]);
        }else{
            dirs[*num]->pid = NULL;
        }
        dirs[*num]->fileType = strdup(sql.row[3]);
        dirs[*num]->filepath = strdup(sql.row[4]);
        dirs[*num]->flag = 0;
        dirs[*num]->isLast = 0;
        ++(*num);
    }
    
    for(int i = 0; i < *num; i++) {
        // printf("---------- %d\n",i);
        if (strcmp(dirs[i]->fileType, "d") == 0) {
            // 初始化目录结构体
            // printf("第 %d 次为文件夹类型\n",i);
            init_dir(dirs[i], 10);
            // printf("第 %d 次初始化完毕\n",i);
            // 添加子节点到对应的父目录
            for (int j = 0; j < *num; j++) {
                // if (i != j && dirs[j]->pid != NULL)
                // {
                //     printf("当前比较：%s,%s,文件：%s,flag = %d,比较结果是：%d,二者 %s,%s\n",dirs[i]->filename,dirs[j]->filename,dirs[j]->pid,dirs[j]->flag,strcmp(dirs[i]->file_id,dirs[j]->pid),dirs[i]->file_id,dirs[j]->pid);
                // }
                if (strcmp(dirs[j]->pid,"-1") != 0 && i != j && dirs[j]->flag == 0 && strcmp(dirs[i]->file_id,dirs[j]->pid) == 0) {
                    add_element(dirs[i], dirs[j]);
                    // printf("当前文件夹为：%s,收纳的文件是：%s,类型是：%s,文件当前收纳大小是：%d\n",dirs[i]->filename,dirs[j]->filename,dirs[j]->fileType,dirs[i]->size);
                }
                if(dirs[i]->size > 0 && j == *num -1){
                    // sortDir(dirs[i]);
                    // // printf("1\n");
                    printf("%s,%d\n",dirs[i]->filename,dirs[i]->size);
                    qsort(dirs[i]->arr, dirs[i]->size, sizeof(DIR_S*), compareDir);
                    DIR_S **tmp = (DIR_S **)dirs[i]->arr;
                    if (dirs[i]->size > 0) { 
                        tmp[dirs[i]->size - 1]->isLast = 1; 
                    }
                }
                
            }
        }
    }
    // 打印根目录下的树形结构

    // for(int i = 0; i < *num; i++) {
    //     if (strcmp(dirs[i]->fileType, "d") == 0 && dirs[i]->pid == NULL) {
    //         printTree(dirs[i], 0);
    //         break;
    //     }
    // }

cleanup:
    mysql_free_result(sql.res);
    free(sentence);
    free(sql.para[0]);
    free(sql.para[1]);
    free(sql.para[2]);
    free(sql.para[3]);
    free(sql.para[4]);
    free(sql.para[5]);
    free(sql.para);
    
    if (*num > 0)
    {
        return dirs;
    }
    return NULL;
}

void getTree(DIR_S *dir, int depth, char *buffer, int *offset) {
    for (int i = 0; i < depth; i++) {
        if (*offset < BUFFER_SIZE - 2) {
            snprintf(buffer + *offset, BUFFER_SIZE - *offset, "  ");
            *offset += 2;
        } else {
            return;
        }
    }
    int n = 0;
    if (dir->isLast == 1) {
        n = snprintf(buffer + *offset, BUFFER_SIZE - *offset, "└── %s (%s) \n", dir->filename, dir->fileType);
    } else {
        n = snprintf(buffer + *offset, BUFFER_SIZE - *offset, "├── %s (%s) \n", dir->filename, dir->fileType);
    }
    if (n < 0 || n >= BUFFER_SIZE - *offset) 
        return;

    *offset += n;
    for (int j = 0; j < dir->size; j++) {
        if (*offset < BUFFER_SIZE - 4) {
            n = snprintf(buffer + *offset, BUFFER_SIZE - *offset, "│   ");
            if (n < 0 || n >= BUFFER_SIZE - *offset) return;
            *offset += n;
        } else {
            return;
        }
        getTree((DIR_S*)dir->arr[j], depth + 1, buffer, offset);
    }
}


void collect(DIR_S *dir, char *buffer, int *offset) {
    int n = 0;
    if (*offset == 0){
        n = snprintf(buffer + *offset, BUFFER_SIZE - *offset, " ( %s ",dir->file_id);
    }else{
        n = snprintf(buffer + *offset, BUFFER_SIZE - *offset, ",%s", dir->file_id);
    }
    if (n < 0 || n >= BUFFER_SIZE - *offset) 
        return;
    *offset += n;
    for (int j = 0; j < dir->size; j++) {
        collect((DIR_S*)dir->arr[j],  buffer, offset);
    }
}

// //测试代码
// int main(){
//     int num = 0,offset = 0;
//     DIR_S** dirs;
//     char *uid = "1";
//     dirs = (DIR_S** )queryVFS(uid,&num);
//     char *buffer = (char *)malloc(4096 * sizeof(char));
//     for(int i = 0; i < num; i++) {
//         printf("-----------1\n");
//         if (strcmp(dirs[i]->filepath, "/documents")  == 0)
//         {
//             printf("-----------%s\n",dirs[i]->filepath);
//             getTree(dirs[i], 0,buffer,&offset);
//             break;
//         }
//         printf("-----------3\n");
//         // if(strcmp(dirs[i]->fileType, "d") == 0 && dirs[i]->pid == NULL) {
//         //     getTree(dirs[i], 0,buffer,&offset);
//         //     break;
//         // }
//     }
//     printf("%s\n", buffer);

//     free(buffer); 
//     freeDirs(dirs,num);
// }

